#include "stm32f10x.h"  
#include "Delay.h"

#define I2C_PORT GPIOB
#define SCL_PIN GPIO_Pin_10
#define SDA_PIN GPIO_Pin_11

void I2C_Soft_WriteSCL(u8 bitValue)
{
	GPIO_WriteBit(I2C_PORT,SCL_PIN,(BitAction)bitValue);
	Delay_us(10);
}

void I2C_Soft_WriteSDA(u8 bitValue)
{
	GPIO_WriteBit(I2C_PORT,SDA_PIN,(BitAction)bitValue);
	Delay_us(10);
}

u8 I2C_Soft_ReadSDA(void)
{
	u8 BitValue;
	BitValue = GPIO_ReadInputDataBit(I2C_PORT,SDA_PIN);
	Delay_us(10);
	return BitValue;
}

void I2C_Soft_Init(void) {
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = SCL_PIN | SDA_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;//开漏输出，即高电平浮空
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_SetBits(I2C_PORT,GPIO_Pin_10 | GPIO_Pin_11);
}

void I2C_Soft_Start(void)
{
	I2C_Soft_WriteSDA(1); //先保证两者为高电平，并兼容重复起始
	I2C_Soft_WriteSCL(1); //先释放SCL有可能触发终止条件
	I2C_Soft_WriteSDA(0); //SDA在SCL高时被拉下，触发起始
	I2C_Soft_WriteSCL(0); //拉低SCL，方便后续
}

void I2C_Soft_Stop(void)
{
	I2C_Soft_WriteSDA(0);
	I2C_Soft_WriteSCL(1);
	I2C_Soft_WriteSDA(1); //SDA在SCL高时被释放，触发终止
}

void I2C_Soft_SendByte(u8 Byte)
{
	u8 pointer = 0x80;
	for(;pointer>0;pointer>>=1){
		I2C_Soft_WriteSDA(Byte & pointer);
		I2C_Soft_WriteSCL(1);
		I2C_Soft_WriteSCL(0);
	}
	I2C_Soft_WriteSDA(1);
}

u8 I2C_Soft_ReceiveByte(void)
{
	I2C_Soft_WriteSDA(1);
	u8 offset = 8;
	u8 Byte = 0;
	while(offset>0){
		offset--;
		I2C_Soft_WriteSCL(1);
		Byte |= I2C_Soft_ReadSDA() << offset;
		I2C_Soft_WriteSCL(0);
	}
	//I2C_Soft_WriteSDA(0);
	return Byte;
}

void I2C_Soft_SendAck(u8 AckBit)
{
	I2C_Soft_WriteSDA(AckBit);
	I2C_Soft_WriteSCL(1);
	I2C_Soft_WriteSCL(0);
}

u8 I2C_Soft_ReceiveAck(void)
{
	u8 AckBit;
	I2C_Soft_WriteSCL(1);
	AckBit = I2C_Soft_ReadSDA();
	I2C_Soft_WriteSCL(0);
	return AckBit;
}
